package game.room;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.Transparency;
import java.awt.image.BufferedImage;

import applet.Screen;
import applet.resource.Sprite2D;

/** */
public class TerrainRenderer {
	/** */
	public enum Mask {
		/** Wall only. */
		NNNN(-1, -1), NNNW(2, 0), NNWN(2, 4), NNWW(1, 2),
		/** */
		NWNN(1, 0), NWNW(0, 0), NWWN(1, 3), NWWW(2, 1),
		/** */
		WNNN(1, 4), WNNW(1, 1), WNWN(0, 4), WNWW(2, 3),
		/** */
		WWNN(0, 2), WWNW(0, 3), WWWN(0, 1), WWWW(2, 2),

		/** Left stair. */
		NWNS(3, 0), WWSW(3, 1), NSNS(4, 0),
		/** */
		SWSW(4, 1), NSNW(5, 0), SWWW(5, 1),

		/** Right stair. */
		WNSN(3, 4), WWWS(3, 3), SNSN(4, 4),
		/** */
		WSWS(4, 3), SNWN(5, 4), WSWW(5, 3),

		/** Tunnel. */
		WTNN(3, 2), TTNN(4, 2), TWNN(5, 2);

		/** */
		private final int row;
		/** */
		private final int col;

		/**
		 * @param newRow - the row in which this tile is to be found.
		 * @param newCol - the column in which this tile is to be
		 *        found.
		 */
		private Mask(final int newRow, final int newCol) {
			row = newRow;
			col = newCol;
		}

		/** @return the row. */
		public final int getRow() {
			return row;
		}

		/** @return the column. */
		public final int getCol() {
			return col;
		}
	}

	/** */
	private static final Sprite2D TILES =
		new Sprite2D("terrain/jungle-5-tiles.png", 5, 6);

	/** */
	private BufferedImage[] layerImage;

	/** */
	public TerrainRenderer() {
		layerImage = new BufferedImage[Room.LAYERS];
	}

	/**
	 * @param canvas -
	 * @param room -
	 * @param layer -
	 */
	public final void render(final Canvas canvas, final Room room,
		final int layer) {
		layerImage[layer] =
			GraphicsEnvironment.getLocalGraphicsEnvironment()
				.getDefaultScreenDevice().getDefaultConfiguration()
				.createCompatibleImage(Screen.WIDTH, Screen.HEIGHT,
					Transparency.TRANSLUCENT);
		Graphics2D g = layerImage[layer].createGraphics();

		for (int r = 0; r < Room.ROWS - 1; ++r) {
			for (int c = 0; c < Room.COLS - 1; ++c) {
				String maskString =
					room.getTerrainString(layer, r, c, layer, r + 1, c + 1);

				try {
					Mask mask = Mask.valueOf(maskString);
					if (mask != Mask.NNNN) {
						TILES.draw(g, mask.getCol(), mask.getRow(), c
							* Cell.WIDTH, r * Cell.HEIGHT);
					}
				} catch (Exception e) {
					// Was land-locked tunnel.
					maskString = maskString.replaceAll("T", "W");
					try {
						Mask mask = Mask.valueOf(maskString);
						if (mask != Mask.NNNN) {
							TILES.draw(g, mask.getCol(), mask.getRow(), c
								* Cell.WIDTH, r * Cell.HEIGHT);
						}
					} catch (Exception e2) {
						// Was unknown stair
						maskString = maskString.replaceAll("S", "W");
						Mask mask = Mask.valueOf(maskString);
						if (mask != Mask.NNNN) {
							TILES.draw(g, mask.getCol(), mask.getRow(), c
								* Cell.WIDTH, r * Cell.HEIGHT);
						}
					}
				}
			}
		}
		final Color col = new Color(255, 255, 255, 32);
		g.setColor(col);
		for (int r = 0; r < Room.ROWS - 1; ++r) {
			for (int c = 0; c < Room.COLS - 1; ++c) {
				String s =
					room.getTerrainString(layer, r, c, layer, r + 1, c + 1);
				if (s.charAt(0) == 'T') {
					g.fillRect(c * Cell.WIDTH, r * Cell.HEIGHT, Cell.WIDTH / 2,
						Cell.HEIGHT / 2);
				}
				if (s.charAt(1) == 'T') {
					g.fillRect(c * Cell.WIDTH + Cell.WIDTH / 2,
						r * Cell.HEIGHT, Cell.WIDTH / 2, Cell.HEIGHT / 2);
				}
				if (s.charAt(2) == 'T') {
					g.fillRect(c * Cell.WIDTH, r * Cell.HEIGHT + Cell.HEIGHT
						/ 2, Cell.WIDTH / 2, Cell.HEIGHT / 2);
				}
				if (s.charAt(3) == 'T') {
					g.fillRect(c * Cell.WIDTH + Cell.WIDTH / 2, r * Cell.HEIGHT
						+ Cell.HEIGHT / 2, Cell.WIDTH / 2, Cell.HEIGHT / 2);
				}
			}
		}
		g.dispose();
	}

	/**
	 * @param g -
	 * @param x -
	 * @param y -
	 */
	public final void draw(final Graphics g, final int x, final int y) {
		for (int layer = 0; layer < Room.LAYERS; ++layer) {
			g
				.drawImage(layerImage[layer], x, y - layer * Cell.HEIGHT / 2,
					null);
		}
	}
}
